package com.powerbank.paymentcenter.mq.transaction;

import com.powerbank.common.event.payment.PaymentSuccessEvent;
import com.powerbank.paymentcenter.service.PaymentService;
import lombok.extern.slf4j.Slf4j;
import org.apache.rocketmq.spring.annotation.RocketMQTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionListener;
import org.apache.rocketmq.spring.core.RocketMQLocalTransactionState;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.messaging.Message;
import org.springframework.stereotype.Component;

/**
 * 支付事务消息监听器
 * 确保支付状态更新和消息发送的一致性
 */
@Slf4j
@Component
@RocketMQTransactionListener
public class PaymentTransactionListener implements RocketMQLocalTransactionListener {

    @Autowired
    private PaymentService paymentService;

    @Override
    public RocketMQLocalTransactionState executeLocalTransaction(Message msg, Object arg) {
        try {
            log.info("执行支付本地事务: arg={}", arg);
            
            // arg参数通常是支付单号或相关业务标识
            String paymentNo = (String) arg;
            
            // 执行本地事务：更新支付状态为成功
            boolean success = paymentService.confirmPaymentSuccess(paymentNo);
            
            if (success) {
                log.info("支付本地事务执行成功: paymentNo={}", paymentNo);
                return RocketMQLocalTransactionState.COMMIT;
            } else {
                log.warn("支付本地事务执行失败: paymentNo={}", paymentNo);
                return RocketMQLocalTransactionState.ROLLBACK;
            }
            
        } catch (Exception e) {
            log.error("支付本地事务执行异常: arg={}", arg, e);
            return RocketMQLocalTransactionState.ROLLBACK;
        }
    }

    @Override
    public RocketMQLocalTransactionState checkLocalTransaction(Message msg) {
        try {
            // 从消息中获取支付单号
            String paymentNo = extractPaymentNoFromMessage(msg);
            log.info("检查支付本地事务状态: paymentNo={}", paymentNo);
            
            // 查询支付状态
            Integer paymentStatus = paymentService.getPaymentStatus(paymentNo);
            
            if (paymentStatus == null) {
                log.warn("支付记录不存在: paymentNo={}", paymentNo);
                return RocketMQLocalTransactionState.ROLLBACK;
            }
            
            if (paymentStatus == 1) { // 1表示支付成功
                log.info("支付已成功，提交事务: paymentNo={}", paymentNo);
                return RocketMQLocalTransactionState.COMMIT;
            } else if (paymentStatus == 2 || paymentStatus == 3) { // 2表示失败，3表示取消
                log.info("支付已失败或取消，回滚事务: paymentNo={}, status={}", paymentNo, paymentStatus);
                return RocketMQLocalTransactionState.ROLLBACK;
            } else {
                log.info("支付状态未知，等待下次检查: paymentNo={}, status={}", paymentNo, paymentStatus);
                return RocketMQLocalTransactionState.UNKNOWN;
            }
            
        } catch (Exception e) {
            log.error("检查支付本地事务状态异常", e);
            return RocketMQLocalTransactionState.UNKNOWN;
        }
    }

    /**
     * 从消息中提取支付单号
     */
    private String extractPaymentNoFromMessage(Message msg) {
        try {
            // 尝试从消息头获取
            Object paymentNo = msg.getHeaders().get("paymentNo");
            if (paymentNo != null) {
                return paymentNo.toString();
            }
            
            // 如果消息体是PaymentSuccessEvent，从中获取
            Object payload = msg.getPayload();
            if (payload instanceof PaymentSuccessEvent) {
                PaymentSuccessEvent event = (PaymentSuccessEvent) payload;
                return event.getPaymentId();
            }
            
            log.warn("无法从消息中提取支付单号: headers={}, payload={}", 
                    msg.getHeaders(), msg.getPayload());
            return null;
            
        } catch (Exception e) {
            log.error("提取支付单号失败", e);
            return null;
        }
    }
}